﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Codemi.Common.Helpers
{
    public static class BootStraper
    {
        public static T Initialize<T>()
        {
            string expectedImplementation = ConfigHelper.GetValueFromConfig(typeof(T).Name+"Implementation", null);
            if (expectedImplementation != null)
            {
                return GetMemberOfType<T>(expectedImplementation);
            }
            else
            {
                return GetMemberImplementingInterface<T>();
            }
        }

        private static T GetMemberOfType<T>(string expectedImplementation)
        {
            foreach (Assembly asembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (Type type in asembly.GetTypes())
                {
                    if (type.Namespace +"." + type.Name == expectedImplementation)
                    {
                         ConstructorInfo info = type.GetConstructor(new Type[] {});
                         return (T)info.Invoke(new object[] { });
                    }
                }
            }
            throw new NotImplementedException(string.Format("Cannot find assembly containing {0} type", expectedImplementation));
        }

        private static T GetMemberImplementingInterface<T>()
        {
            if (typeof(T).IsInterface)
            {

                foreach (Assembly asembly in AppDomain.CurrentDomain.GetAssemblies())
                {
                    foreach (Type type in asembly.GetTypes())
                    {
                        if (type.GetInterfaces().Contains(typeof(T)))
                        {
                            ConstructorInfo info = type.GetConstructor(new Type[] { });
                            return (T)info.Invoke(new object[] { });
                        }
                    }
                }
                throw new NotImplementedException(string.Format("Cannot find assembly implementing interface {0}", typeof(T).Name));
            }
            else
            {
                throw new Exception(string.Format("{0} is not an interface", typeof(T).Name));
            }
        }
    }
}
